﻿using System;
using System.Drawing;
using ProjectAutumn.Graphics;
using SlimDX.Direct2D;
using Color = ProjectAutumn.Graphics.Color;

namespace ProjectAutumn.GraphicsDevice.Direct2D
{
    class Direct2DGraphicsDevice : Graphics.GraphicsDevice
    {
        private readonly Factory factory;
        private readonly WindowRenderTarget renderTarget;
        public Direct2DGraphicsDevice(Game game)
                : base(game)
        {
            FactoryType type = FactoryType.SingleThreaded;
            if(Environment.ProcessorCount > 1)
                type = FactoryType.MultiThreaded;
#if DEBUG
            const DebugLevel DEBUG = DebugLevel.Error;
#else
            const DebugLevel DEBUG = DebugLevel.None;
#endif
            factory = new Factory(type, DEBUG);
            renderTarget = new WindowRenderTarget(factory,
                new WindowRenderTargetProperties
            {
                    Handle = Game.WindowDevice.Handle,
            });
        }
        public override void Clear(Color color)
        {
            renderTarget.Clear(ConvertColor(color));
        }
        protected override Texture LoadTexture(string file)
        {
            return new Direct2DTexture(file, renderTarget);
        }
        protected override void BeginDraw() { renderTarget.BeginDraw(); }
        public override void Begin2D() { }
        public override void End2D() { }
        public override void Draw(Texture texture, Vector2 position, Rectangle? source, Color tint, float rotation, Vector2 offset, float scale)
        {
            if (source != null) throw new NotImplementedException();
            if (rotation != 0) throw new NotImplementedException();
            if (scale != 1) throw new NotImplementedException();
            if (tint != Color.White) throw new Exception();
            Direct2DTexture direct = (Direct2DTexture)texture;
            BitmapBrush brush = new BitmapBrush(renderTarget, direct.Internal);
            renderTarget.DrawBitmap(direct.Internal, new RectangleF(position.X - offset.X, position.Y - offset.Y, texture.Width, texture.Height));
            brush.Dispose();
        }
        protected override void EndDraw() { renderTarget.EndDraw(); }
        public override int Width
        {
            get { return (int)renderTarget.Size.Width; }
        }
        public override int Height
        {
            get { return (int)renderTarget.Size.Height; }
        }
        public override Texture CreateTexture(int width, int height)
        {
            return new Direct2DTexture(width, height, renderTarget);
        }
        protected override void SetMouseVisibility(bool value)
        {
            //TODO: Change the mouse visibility
        }
        protected override void ApplyChanges(int width, int height, bool isFullscreen)
        {
            if (isFullscreen) throw new NotImplementedException("Direct2D doesn't yet support fullscreen.");
            renderTarget.Resize(new Size(width, height));
        }
        public override GraphicCapabilities GraphicCapabilities
        {
            get {
                return new GraphicCapabilities
                {
                        SupportsChangingMouseVisibility = false,
                        SupportsClearing = true,
                        SupportsDrawing2D = true,
                        SupportsDrawingRotation = false,
                        SupportsDrawingScale = false,
                        SupportsDrawingSource = false,
                        SupportsDrawingTint = false,
                        SupportsDynamicTextures = true,
                        SupportsFullscreen = false,
                        SupportsLoadingTextureFile = false,
                        SupportsTextureSetData = true,
                };
            }
        }
        public override void Dispose()
        {
            renderTarget.Dispose();
            factory.Dispose();
        }
    }
}
